package com.mc.lp.database.service.handler;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.dao.DataAccessException;

import com.mc.lp.database.entity.GradeYearMapperEntity;
import com.mc.lp.database.entity.MicroCampusEntity;
import com.mc.lp.database.entity.helper.GradeYearMapperHelper;
import com.mc.lp.database.exception.ConcurrentAccessException;
import com.mc.lp.database.service.handler.constant.FormRequestType;
import com.mc.lp.service.GradeYearMapperService;
import com.mc.lp.service.MicroCampusEntityService;
import com.mc.lp.shared.util.constants.ResponseStatus;
import com.mc.lp.shared.vo.GradeMappingVo;
import com.mc.lp.shared.vo.IValueObject;
import com.mc.lp.shared.vo.ServiceResponse;
import com.mc.lp.shared.vo.SimpleResponse;
import com.mc.lp.shared.vo.StudentRecordVO;

/**
 * handler all request related to student records saving and fetching
 * information.
 * 
 * @author deepak
 * 
 */
public class GradeMappingHandler extends AbstractFormHandler<IValueObject, IValueObject> {

	
	@Resource
	GradeYearMapperService gradeYearMapperService;
	
	@Resource
	MicroCampusEntityService microCampusEntityService;
	/**
	 * this method will tell how many request this handler can handle
	 */
	public HashSet<FormRequestType> getRequestHandlingType() {
		HashSet<FormRequestType> handledRequest = new HashSet<FormRequestType>();
		handledRequest.add(FormRequestType.MAP_GRADE);
		handledRequest.add(FormRequestType.DELETE_GRADE_MAPPING);
		handledRequest.add(FormRequestType.GET_GRADE_MAPPING);
		return handledRequest;
	}

	@Override
	public IValueObject serveRequest(FormRequestType requestType, IValueObject object) throws DataAccessException, ConcurrentAccessException {
		SimpleResponse response = new SimpleResponse();
		response.setId(1);
		response.setMsg("No case matched to perform operation, please check request type");

		switch (requestType) {
		case MAP_GRADE: // you will get GradeMappingVo, this is upsert
			return saveGradeMapping(requestType, (StudentRecordVO) object);
		case DELETE_GRADE_MAPPING: // you will get grade id and student id in
									// GradeMappingVo
			return deleteGradeMapping(requestType, (StudentRecordVO) object);
		case GET_GRADE_MAPPING: // return list of GradeMappingVo in service
								// response.
			return getGradeMapping(requestType, (StudentRecordVO) object);
		default:
			break;
		}
		return response;
	}

	private IValueObject saveGradeMapping(FormRequestType requestType, StudentRecordVO object) {
		// AP BLOCKER 23rd March
		ServiceResponse<GradeMappingVo> response = new ServiceResponse<GradeMappingVo>();
		GradeMappingVo vo = object.getGradeMapping();
		GradeYearMapperHelper helper = new GradeYearMapperHelper();

		try {
			MicroCampusEntity entity = microCampusEntityService.getEntityById(vo.getStudentId());
			Set<GradeYearMapperEntity> mappingSet = new HashSet<GradeYearMapperEntity>();
			mappingSet = entity.getGradeYearMapper();
			
			if(null!= vo.getId()){
				for (GradeYearMapperEntity en : mappingSet) {
					if(vo.getId()==en.getId()){
						helper.setEntity(vo, en);
						en.setEntity(entity);
						break;
					}
				}
			}else{
				GradeYearMapperEntity ent = helper.getEntity(vo);	
				ent.setEntity(entity);
				mappingSet.add(ent);
			}

			microCampusEntityService.saveMicroCampusEntity(entity);
			response.setStatus(ResponseStatus.SUCCESS);
			response.setMsg("Saved successfully");
			
		} catch (Exception e) {
			response.setStatus(ResponseStatus.FAILED);
			response.setMsg("Saved Failed");
		}
		// return success or failure based on operation performed
		return response;
	}

	private IValueObject getGradeMapping(FormRequestType requestType, StudentRecordVO object) {
		// TODO Auto-generated method stub
		ServiceResponse<GradeMappingVo> response = new ServiceResponse<GradeMappingVo>();
		GradeMappingVo vo = object.getGradeMapping();
		GradeYearMapperHelper helper = new GradeYearMapperHelper();
		List<GradeMappingVo> voList = new ArrayList<GradeMappingVo>();
		
		MicroCampusEntity entity = microCampusEntityService.getEntityById(object.getSearchCriteria().getStudentEntityId());
		Set<GradeYearMapperEntity> mappingSet = new HashSet<GradeYearMapperEntity>();
		mappingSet = entity.getGradeYearMapper();

		for (GradeYearMapperEntity en : mappingSet) {
			voList.add(helper.getVO(en));
		}
		
	/*	GradeMappingVo vo = new GradeMappingVo();
		vo.setId(1L);
		vo.setGradeId(1L);
		vo.setGradeName("Nursary");
		vo.setStartYear("2012");
		vo.setEndYear("2013");

		GradeMappingVo vo1 = new GradeMappingVo();
		vo.setId(2L);
		vo1.setGradeId(3L);
		vo1.setGradeName("Second");
		vo1.setStartYear("2013");
		vo1.setEndYear("2014");
		response.setResult(Arrays.asList(vo, vo1));
*/
		
		response.setResult(voList);
		response.setStatus(ResponseStatus.SUCCESS);
		return response;
	}

	private IValueObject deleteGradeMapping(FormRequestType requestType, StudentRecordVO object) {
		ServiceResponse<GradeMappingVo> response = new ServiceResponse<GradeMappingVo>();
		GradeMappingVo vo = object.getGradeMapping();

		try {

			MicroCampusEntity entity = microCampusEntityService.getEntityById(vo.getStudentId());
			Set<GradeYearMapperEntity> set = new HashSet<GradeYearMapperEntity>();
			set = entity.getGradeYearMapper();
			Iterator<GradeYearMapperEntity> iter = set.iterator();
			while (iter.hasNext()) {
				GradeYearMapperEntity en = iter.next();
				if (en.getId() == vo.getId()) {
					iter.remove();
				}
			}
			microCampusEntityService.saveMicroCampusEntity(entity);
			response.setStatus(ResponseStatus.SUCCESS);
			response.setMsg("Deleted successfully");

		} catch (Exception e) {
			response.setStatus(ResponseStatus.FAILED);
			response.setMsg("Deleted Failed");
		}
		return response;
	}

}
